package order

import (
	"context"
	"errors"
	dto "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/dto/business_opportunity"
	orderRepo "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/repository/business_opportunity"
	pb "git.mycaigou.com/gfyx/micro-gfyx-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/business_opportunity"
)

type orderService struct {
	orderRepo orderRepo.OrderRepositoryIface
}

func NewOrderService(orderRepo orderRepo.OrderRepositoryIface) OrderServiceIface {
	return &orderService{
		orderRepo: orderRepo,
	}
}

func (s *orderService) SaveOrder(ctx context.Context, request *dto.SaveOrderRequest) (*dto.SaveOrderResponse, error) {
	resp, err := s.orderRepo.SaveOrder(ctx, &pb.SaveOrderRequest{
		Type:      request.Type,
		Condition: request.Condition,
		Id:        request.Id,
		Number:    request.Number,
	})
	if err != nil {
		return nil, err
	}

	if resp == nil {
		return nil, errors.New("保存订单失败")
	}

	return &dto.SaveOrderResponse{
		Id:     resp.Id,
		IsPaid: resp.IsPaid,
	}, nil
}

func (s *orderService) PreviewOrder(ctx context.Context, request *dto.PreviewOrderRequest) (*dto.PreviewOrderResponse, error) {
	resp, err := s.orderRepo.PreviewOrder(ctx, &pb.PreviewOrderRequest{
		Type:      request.Type,
		Condition: request.Condition,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("预览订单信息失败")
	}
	return &dto.PreviewOrderResponse{
		Type:         resp.Type,
		Digest:       resp.Digest,
		Fields:       resp.Fields,
		Price:        float32(resp.Price) / 100,
		UnusedNumber: resp.UnusedNumber,
		Total:        resp.Total,
	}, nil
}

func (s *orderService) GetOrderList(ctx context.Context, request *dto.GetOrderListRequest) (*dto.GetOrderListResponse, error) {
	pbRequest := &pb.GetOrderListRequest{
		Keyword:        request.Keyword,
		PaymentTimeMin: request.PaymentTimeMin,
		PaymentTimeMax: request.PaymentTimeMax,
		PaymentWay:     request.PaymentWay,
		Type:           request.Type,
		Status:         request.Status,
		Page:           request.Page,
		PageSize:       request.PageSize,
	}
	if request.PageSize <= 0 {
		pbRequest.PageSize = 20
	}
	if request.Page <= 0 {
		pbRequest.Page = 1
	}

	resp, err := s.orderRepo.GetOrderList(ctx, pbRequest)
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("获取订单列表失败")
	}

	result := &dto.GetOrderListResponse{
		List:  []*dto.OrderDetail{},
		Total: resp.Total,
	}
	for _, orderItem := range resp.List {
		result.List = append(result.List, &dto.OrderDetail{
			Id:            orderItem.Id,
			Type:          orderItem.Type,
			Digest:        orderItem.Digest,
			Fields:        orderItem.Fields,
			Price:         float32(orderItem.Price) / 100,
			Number:        orderItem.Number,
			Amount:        float32(orderItem.Amount) / 100,
			Status:        orderItem.Status,
			PaymentWay:    orderItem.PaymentWay,
			ResultFileUrl: orderItem.ResultFileUrl,
			CreatedTime:   orderItem.CreatedOn,
			PaymentTime:   orderItem.PaymentTime,
			ExpiredTime:   orderItem.PaymentTime,
		})
	}
	return result, nil
}

func (s *orderService) GetOrderDetail(ctx context.Context, request *dto.GetOrderDetailRequest) (*dto.OrderDetail, error) {
	resp, err := s.orderRepo.GetOrderDetail(ctx, &pb.GetOrderDetailRequest{
		Id: request.Id,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.Order == nil {
		return nil, errors.New("获取订单详情失败")
	}

	return &dto.OrderDetail{
		Id:            resp.Order.Id,
		Type:          resp.Order.Type,
		Digest:        resp.Order.Digest,
		Fields:        resp.Order.Fields,
		Price:         float32(resp.Order.Price) / 100,
		Number:        resp.Order.Number,
		Amount:        float32(resp.Order.Amount) / 100,
		PaymentWay:    resp.Order.PaymentWay,
		Status:        resp.Order.Status,
		CreatedTime:   resp.Order.CreatedOn,
		PaymentTime:   resp.Order.PaymentTime,
		ExpiredTime:   resp.Order.ExpiredOn,
		ResultFileUrl: resp.Order.ResultFileUrl,
		JobId:         resp.Order.JobId,
		FinishStatus:  resp.Order.FinishStatus,
		UnusedNumber:  resp.Order.UnusedNumber,
		Total:         resp.Order.Total,
	}, nil
}
